package com.hznu.stmanage.realm;

import com.hznu.stmanage.entity.Manager;
import com.hznu.stmanage.entity.Student;
import com.hznu.stmanage.entity.Teacher;
import com.hznu.stmanage.service.ManagerService;
import com.hznu.stmanage.service.StudentService;
import com.hznu.stmanage.service.TeacherService;
import com.hznu.stmanage.utils.Util;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.logging.Logger;

/**
 * Created by J_Vino on 16/3/14.
 */
public class UserRealm extends AuthorizingRealm{

    @Autowired
    StudentService studentService;

    @Autowired
    TeacherService teacherService;

    @Autowired
    ManagerService managerService;


    /**
     * 权限注入
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        String principal = principalCollection.getPrimaryPrincipal().toString().trim();
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        HashSet<String> rolesSet=new HashSet<String>();

        if(NumberUtils.isDigits(principal)){//用户名为纯数字则是学号或者工号
            //学生
            Student student = studentService.findByID(principal);
            if(null != student){
                rolesSet.add("student");//学生

                authorizationInfo.setRoles(rolesSet);
                return authorizationInfo;
            }
            //教师
            Teacher teacher = teacherService.findByID(principal);
            if(null != teacher){
                switch (teacher.getLevel()){
                    case 1:
                        rolesSet.add("teacher");//普通教师
                        break;
                    case 2:
                        rolesSet.add("deptHead");//系主任
                        break;
                    default:
                        break;
                }

                authorizationInfo.setRoles(rolesSet);
                return authorizationInfo;

            }
        }

        //管理员
        Manager manager = managerService.findByUsername(principal);
        if(null != manager){
            switch (manager.getCategory()){
                case 1:
                    rolesSet.add("systemManager");//系统管理员
                    break;
                case 2:
                    rolesSet.add("practiceManager");//实践管理员
                    break;
                case 3:
                    rolesSet.add("workManager");//就业管理员
                    break;
                case 4:
                    rolesSet.add("companyManager");//企业管理员
                    break;
                default:
                    break;
            }

            authorizationInfo.setRoles(rolesSet);
            return authorizationInfo;

        }

        return authorizationInfo;
    }

    /**
     * 身份认证
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        //交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配，如果觉得人家的不好可以自定义实现
        SimpleAuthenticationInfo authenticationInfo = null ;

        String principal = authenticationToken.getPrincipal().toString().trim();//可能是学号,工号,用户名

        if(NumberUtils.isDigits(principal)){//用户名为纯数字则是学号或者工号
            //学生
            Student student = studentService.findByID(principal);
            if(null != student){
                authenticationInfo = new SimpleAuthenticationInfo(
                        student.getStudentid(), //学号
                        student.getPassword(), //密码,不用加密直接传入
                        ByteSource.Util.bytes(student.getSalt()),//
                        getName()  //realm name
                );
                Util.threadLocal.set(student);//将学生登录标识存放到本地线程
                return authenticationInfo;
            }
            //教师
            Teacher teacher = teacherService.findByID(principal);
            if(null != teacher){
                authenticationInfo = new SimpleAuthenticationInfo(
                        teacher.getTeacherid(), //工号
                        teacher.getPassword(), //密码,不用加密直接传入
                        ByteSource.Util.bytes(teacher.getSalt()),//
                        getName()  //realm name
                );
                Util.threadLocal.set(teacher);//将教师登录标识存放到本地线程
                return authenticationInfo;

            }
        }

        //管理员
        Manager manager = managerService.findByUsername(principal);
        if(null != manager){
            authenticationInfo = new SimpleAuthenticationInfo(
                    manager.getUsername(), //用户名
                    manager.getPassword(), //密码,不用加密直接传入
                    ByteSource.Util.bytes(manager.getSalt()),//
                    getName()  //realm name
            );
            Util.threadLocal.set(manager);//将管理员登录标识存放到本地线程
            return authenticationInfo;

        }
        throw new UnknownAccountException();//没找到帐号
    }

    @Override
    public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
        super.clearCachedAuthorizationInfo(principals);
    }

    @Override
    public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
        super.clearCachedAuthenticationInfo(principals);
    }

    @Override
    public void clearCache(PrincipalCollection principals) {
        super.clearCache(principals);
    }

    public void clearAllCachedAuthorizationInfo() {
        getAuthorizationCache().clear();
    }

    public void clearAllCachedAuthenticationInfo() {
        getAuthenticationCache().clear();
    }

    public void clearAllCache() {
        clearAllCachedAuthenticationInfo();
        clearAllCachedAuthorizationInfo();
    }
}
